package com.example.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.dto.CodeTool.CodeTool;
import com.example.entity.vo.request.code.MD5RequestVO;
import com.example.entity.vo.response.code.MD5ResponseVO;
import com.example.mapper.CodeToolMapper;
import com.example.service.CodeToolService;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * CodeToolService实现类
 *
 * @auth shanyue
 * @date 2025年07月07日10:39
 */
@Service
public class CodeToolServiceImpl extends ServiceImpl<CodeToolMapper, CodeTool> implements CodeToolService {

    /**
     * 根据工具的唯一路径path查询工具信息
     *
     * @param path 工具路径标识
     * @return 对应的CodeTool实体对象，不存在返回null
     */
    @Override
    public CodeTool getInfoByPath(String path) {
        return lambdaQuery()
                .eq(CodeTool::getPath, path)
                .one();
    }

    /**
     * 根据请求对象中的文本内容，计算并返回MD5哈希值
     *
     * @param md5RequestVO 请求对象，待加密文本
     * @return MD5VO响应对象
     */
    @Override
    public MD5ResponseVO getMd5Hash(MD5RequestVO md5RequestVO) {
        String text = md5RequestVO.getText();
        MD5ResponseVO md5VO = new MD5ResponseVO();

        //若文本为空，返回空对象
        if (text == null || text.isEmpty()) {
            return md5VO;
        }

        //计算32位小写MD5
        String md5Lower32 = md5(text);
        //转换为32位大写MD5
        String md5Upper32 = md5Lower32.toUpperCase();

        //取32位MD5中间16位作为16位小写MD5
        String md5Lower16 = md5Lower32.substring(8, 24);
        //转换位16位大写MD5
        String md5Upper16 = md5Upper32.substring(8, 24);

        //设置结果
        md5VO.setLower32(md5Lower32);
        md5VO.setUpper32(md5Upper32);
        md5VO.setLower16(md5Lower16);
        md5VO.setUpper16(md5Upper16);

        return md5VO;

    }

    /**
     * 进制转换方法，将输入的数字字符串从sourceBase进制转换为targetBase进制
     *
     * @param sourceBase 输入数字的源进制，范围2-36
     * @param targetBase 目标进制，范围2-36
     * @param inputValue 输入的数字
     * @return 转换后的数字字符串，若输入无效则返回错误提示或空字符串
     */
    @Override
    public String numberChange(int sourceBase, int targetBase, String inputValue) {
        if (inputValue == null || inputValue.isEmpty()) {
            return "";
        }
        if (sourceBase < 2 || sourceBase > 36 || targetBase < 2 || targetBase > 36) {
            return "进制范围应在2-36之间";
        }
        BigInteger decimalValue = new BigInteger(inputValue, sourceBase);
        return decimalValue.toString(targetBase).toUpperCase();
    }

    /**
     * 计算文本MD5值，返回32位16进制字符串
     *
     * @param text 待价密文本
     * @return 32位小写MD5字符串
     */
    private String md5(String text) {
        try {
            //获取MD5算法实例
            MessageDigest md = MessageDigest.getInstance("MD5");
            //计算文本的字节数组的MD5摘要
            byte[] bytes = md.digest(text.getBytes(StandardCharsets.UTF_8));

            //将字节数组转换成小写16进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                //通过 & 0xFF 将byte转换成无符号整数，避免负数导致错误
                String hex = Integer.toHexString(b & 0xFF);
                //不足两位补0
                if (hex.length() == 1) {
                    sb.append('0');
                }
                sb.append(hex);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            //当系统不支持MD5算法时，抛出异常
            throw new RuntimeException("MD5加密错误", e);
        }
    }

}
